package com.example.invoker.interceptor;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.invoker.annotation.Auth;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.security.auth.message.AuthException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 鉴权拦截器
 *
 * @author
 * @since 2021-05-26 11:23:27
 */
public class AuthInterceptor implements HandlerInterceptor {

    private static final String AUTHORIZATION = "authorization";
    private static final String BEARER = "Bearer ";
    private static final String ihoment = "ihoment";
    @Value("${govee.token}")
    private String goveeToken;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 判断是否方法级别的,不是直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;

        // 从header中获取token
        String authorization = request.getHeader(AUTHORIZATION);
        if (StringUtils.isBlank(authorization)) {
            //跑出自己的异常
            throw new AuthException("未提供有效token");
        }
        String token = authorization.replace(BEARER, "");

        // 用注解标记拦截位置
        if (handlerMethod.getMethod().getAnnotation(Auth.class) == null) {
            String requestURI = request.getRequestURI();
            if (requestURI.contains("/csBoard")) {
                // 客服看板token验证
                if (!StringUtils.equals(token, goveeToken.replace(BEARER, ""))) {
                    throw new AuthException("未提供有效token");
                }
            } else {
                // 预留
                throw new AuthException("未提供有效token");
            }
        } else {
            // 调用的app看板接口
            DecodedJWT decode = JWT.decode(token);
            String newToken = JWT.create().withIssuer(ihoment)
                    .withClaim("loginTime", decode.getClaim("loginTime").asDate())
                    .withClaim("userId", decode.getClaim("userId").asInt())
                    .sign(Algorithm.HMAC256(ihoment));
            if (!StringUtils.equals(token, newToken)) {
                throw new AuthException("未提供有效token");
            }
        }
        return true;
    }

}
